/*
 *    Copyright (c) 2018-2025, cloud All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: cloud
 */
package com.fuyao.cloud.space.storey.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.common.core.constant.CommonConstants;
import com.fuyao.cloud.common.core.util.R;
import com.fuyao.cloud.common.data.datascope.DataScope;
import com.fuyao.cloud.common.data.resolver.NumberResolver;
import com.fuyao.cloud.space.constant.EdificeConstant;
import com.fuyao.cloud.space.constant.RegionalConstant;
import com.fuyao.cloud.space.constant.StoreyConstant;
import com.fuyao.cloud.space.dto.RoomStoreyDTO;
import com.fuyao.cloud.space.edifice.service.RoomEdificeService;
import com.fuyao.cloud.space.entity.RoomEdifice;
import com.fuyao.cloud.space.entity.RoomHouse;
import com.fuyao.cloud.space.entity.RoomStorey;
import com.fuyao.cloud.space.house.mapper.RoomHouseMapper;
import com.fuyao.cloud.space.storey.mapper.RoomStoreyMapper;
import com.fuyao.cloud.space.storey.service.RoomStoreyService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 楼层管理
 *
 * @author 时间的朋友
 * @date 2021-11-11 15:30:25
 */
@Service
@RequiredArgsConstructor
public class RoomStoreyServiceImpl extends ServiceImpl<RoomStoreyMapper, RoomStorey> implements RoomStoreyService {
	private final RoomEdificeService roomEdificeService;
	private final RoomHouseMapper houseMapper;

	@Override
	public boolean save(RoomStorey entity) {
		beforeSaveOrUpdate(entity);
		return super.save(entity);
	}

	@Override
	public boolean updateById(RoomStorey entity) {
		beforeSaveOrUpdate(entity);
		return super.updateById(entity);
	}

	@Override
	public boolean saveList(RoomStoreyDTO fyRoomStoreyDTO) {
		for (int i = fyRoomStoreyDTO.getStart();i <= fyRoomStoreyDTO.getEnd(); i++) {
			RoomStorey fyRoomStorey=new RoomStorey();
			BeanUtils.copyProperties(fyRoomStoreyDTO,fyRoomStorey);
			fyRoomStorey.setName(fyRoomStorey.getName()+i);
			fyRoomStorey.setCheckinGender(StoreyConstant.DEFAULT_GENDER);
			if(!this.save(fyRoomStorey)){
				return false;
			}
		}
		return true;
	}

	/**
	 * 保存或新增之前对修改的内容进行编辑
	 * @param entity
	 */
	private void beforeSaveOrUpdate(RoomStorey entity) {
		// 楼栋id不为空
		if (entity.getEdificeId() != null){
			RoomEdifice fyRoomEdifice=this.roomEdificeService.getById(entity.getEdificeId());
			entity.setEdificeName(fyRoomEdifice.getName());
			entity.setDataCode(fyRoomEdifice.getDataCode()+"."+entity.getCode());
		}
		// 自动设置一个编码
		if(StrUtil.isEmpty(entity.getCode())){
			entity.setCode(NumberResolver.getNumberStr(StoreyConstant.DEFAULT_TYPE,StoreyConstant.DEFAULT_CODE).getData());
		}
		// 排序号为零时 自动设置排序号
		if (entity.getOrdernumber()==null || entity.getOrdernumber()==0){
			entity.setOrdernumber(NumberResolver.getNumberValue(StoreyConstant.DEFAULT_TYPE, StoreyConstant.DEFAULT_CODE).getData().intValue());
		}
	}

	@Override
	public List<Tree<String>> selectTree() {
		// 树
		List<TreeNode<String>> collect=getTreeNode();
		return TreeUtil.build(collect, RegionalConstant.REGIONAL_TREE_NAME + ".0");
	}

	@Override
	public List<TreeNode<String>> getTreeNode() {
		// 查询全部楼层
		List<RoomStorey> storeyAllList = baseMapper.selectList(Wrappers.emptyWrapper());

		// 查询数据权限内部门
		List<Long> storeyOwnIdList = baseMapper.selectListByScope(Wrappers.emptyWrapper(), new DataScope()).stream()
				.map(RoomStorey::getDeptId).collect(Collectors.toList());
		// 树
		List<TreeNode<String>> collect= this.roomEdificeService.getTreeNode();

		collect .addAll(storeyAllList.stream()
				.sorted(Comparator.comparing(RoomStorey::getCreateTime)).map(storey -> {
					TreeNode<String> treeNode = new TreeNode();
					treeNode.setId(StoreyConstant.STOREY_TREE_NAME+"."+storey.getId());
					treeNode.setParentId(EdificeConstant.EDIFICE_TREE_NAME+"."+storey.getEdificeId());
					treeNode.setName(storey.getName());
					treeNode.setWeight(storey.getOrdernumber());
					// 有权限不返回标识
					Map<String, Object> extra = new HashMap<>(8);
					extra.put("isLock", !storeyOwnIdList.contains(storey.getDeptId()));
					extra.put("createTime", storey.getCreateTime());
					extra.put("affiliName",StoreyConstant.STOREY_TREE_NAME);
					extra.put("affiliParentName",EdificeConstant.EDIFICE_TREE_NAME);
					extra.put("idCard",storey.getId());
					treeNode.setExtra(extra);
					return treeNode;
				}).collect(Collectors.toList()));
		return collect;
	}

	@Override
	public Page<RoomStorey> getTreePage(Page page, Long id, String affiliName) {
		List<Long> ids=getTreeParam(id,affiliName);
		ids.add(0L); // 如果为空会报错
		return this.baseMapper.selectPage(page,Wrappers.<RoomStorey>lambdaQuery().in(RoomStorey::getId,ids));
	}

	@Override
	public List<Long> getTreeParam(Long id, String affiliName){
		List<Long> ids;
		if (affiliName.equals(EdificeConstant.EDIFICE_TREE_NAME)){
			ids=this.baseMapper.getIdByParentId(new Long[]{id});
		}else {
			List<Long> parentIds= this.roomEdificeService.getTreeParam(id,affiliName);
			if (parentIds.size() == 0){
				return new ArrayList<>();
			}
			ids=this.baseMapper.getIdByParentId(parentIds.toArray(new Long[parentIds.size()]));
		}
		return Optional.ofNullable(ids).orElse(new ArrayList<>());
	}

	@Override
	public List<Tree<String>> lazyTree(String edificeId) {
		String[] ids=edificeId.split("-");
		if (ids.length == 2){
			if (!ids[0].equals(EdificeConstant.EDIFICE_TREE_NAME)){
				return new ArrayList<>();
			}
		}
		return lazyTree(Long.valueOf(ids[1]));
	}

	@Override
	public List<Tree<String>> lazyTree(Long edificeId) {
		// lambda 查询条件
		LambdaQueryWrapper<RoomStorey> wrappers=Wrappers.<RoomStorey>lambdaQuery().eq(RoomStorey::getEdificeId,edificeId);
		// 查询全部楼层
		List<RoomStorey> storeyAllList = baseMapper.selectList(wrappers);

		// 查询数据权限内部门
		List<Long> storeyOwnIdList = baseMapper.selectListByScope(wrappers, new DataScope()).stream()
				.map(RoomStorey::getDeptId).collect(Collectors.toList());
		// 树
		List<TreeNode<String>> collect= storeyAllList.stream()
				.sorted(Comparator.comparing(RoomStorey::getCreateTime)).map(storey -> {
					TreeNode<String> treeNode = new TreeNode();
					treeNode.setId(StoreyConstant.STOREY_TREE_NAME+"."+storey.getId());
					treeNode.setParentId(EdificeConstant.EDIFICE_TREE_NAME+"."+storey.getEdificeId());
					treeNode.setName(storey.getName());
					treeNode.setWeight(storey.getOrdernumber());
					// 有权限不返回标识
					Map<String, Object> extra = new HashMap<>(8);
					extra.put("isLock", !storeyOwnIdList.contains(storey.getDeptId()));
					extra.put("createTime", storey.getCreateTime());
					extra.put("affiliName",StoreyConstant.STOREY_TREE_NAME);
					extra.put("affiliParentName",EdificeConstant.EDIFICE_TREE_NAME);
					extra.put("idCard",storey.getId());
					treeNode.setExtra(extra);
					return treeNode;
				}).collect(Collectors.toList());
		return TreeUtil.build(collect, EdificeConstant.EDIFICE_TREE_NAME+ "."+edificeId);
	}

	@Override
	public boolean removeById(Serializable id) {
		LambdaQueryWrapper<RoomHouse> houseLambdaQueryWrapper = Wrappers.<RoomHouse>lambdaQuery().eq(RoomHouse::getStoreyId, id);
		Long houseCount = houseMapper.selectCount(houseLambdaQueryWrapper);
		Assert.isTrue((houseCount <= 0), "该楼层信息关联房屋信息，请选删除关联房屋信息数据后，再删除楼层数据");
		return super.removeById(id);
	}

	@Override
	public R batchDelete(List<Long> ids) {
		LambdaQueryWrapper<RoomHouse> houseLambdaQueryWrapper = Wrappers.<RoomHouse>lambdaQuery().in(RoomHouse::getStoreyId, ids);
		Long houseCount = houseMapper.selectCount(houseLambdaQueryWrapper);
		Assert.isTrue((houseCount <= 0), "该楼层信息关联房屋信息，请选删除关联房屋信息数据后，再删除楼层数据");

		boolean remove = this.removeByIds(ids);
		if(remove){
			return R.ok(CommonConstants.SUCCESS, String.format("成功删除%s条数据", ids.size()));
		}
		return R.failed(ids,"删除失败");
	}
}
